package com.hxzy.controller;

import com.hxzy.common.annon.RequiresLogin;
import com.hxzy.common.consts.RedisConst;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.security.AdminInfoUtil;
import com.hxzy.common.security.TokenService;
import com.hxzy.common.vo.R;
import com.hxzy.common.web.controller.BaseController;
import com.hxzy.service.SysMenuService;
import com.hxzy.service.SysRoleService;
import com.hxzy.service.SysUserService;
import com.hxzy.system.dto.AdminLoginDTO;
import com.hxzy.system.entity.SysRole;
import com.hxzy.system.vo.AdminLoginVO;
import com.hxzy.system.vo.SysMenuVO;
import com.hxzy.system.vo.router.RouterVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.*;

/**
 * 登录认证
 *
 * @author tonneyyy
 */
@RestController
@Api(tags = "后台登录认证API")
public class AdminLoginController extends BaseController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 获取用户的权限方式，如果true代表实时获取（数据库）,否则获取redis缓存权限
     */
    @Value(value = "${userinfo.permission:false}")
    private boolean userPermisson;


    @ApiOperation(value = "登录认证" )
    @PostMapping(value = "/login")
    public R authentication(@RequestBody @Valid AdminLoginDTO adminLoginDTO){

        //验证验证码是否过期
        String redisKey= RedisConst.getRedisKey(RedisConst.CAPTCHA_KEY,adminLoginDTO.getUuid());
        //查询键是不是存在
        Object redisValue=this.redisTemplate.opsForValue().get(redisKey);

        if(redisValue==null){
            return R.build(AckCode.SMS_CODE_OVERTIME);
        }
        //再判断值是否相等
        if(!redisValue.toString().equalsIgnoreCase(adminLoginDTO.getCode())){
            return R.build(AckCode.SMS_CODE_WRONG);
        }
        //验证码验证成功，删除验证码
        this.redisTemplate.delete(redisKey);


        //用户登录
        AdminLoginVO adminLoginVO = this.sysUserService.login(adminLoginDTO);

        //换令牌
        String jwtToken= this.tokenService.createJwtToken(adminLoginVO);

        //之前这个用户让它失效
        Object hashRedisValue = this.redisTemplate.opsForHash().get(RedisConst.ADMIN_LOGIN_ALL, adminLoginVO.getSysUser().getUserId()+"");
        //该账户有登录过
        if(hashRedisValue!=null){
            String uuidValue=hashRedisValue.toString();
            String stringRedisKey=RedisConst.getRedisKey(RedisConst.ADMIN_LOGIN_KEY,uuidValue);
            //删除之前的登录uuid
            this.redisTemplate.delete(stringRedisKey);
        }
        //写入本次的登录uuid
        this.redisTemplate.opsForHash().put(RedisConst.ADMIN_LOGIN_ALL, adminLoginVO.getSysUser().getUserId()+"", adminLoginVO.getUuid());

        return R.okHasData(jwtToken);
    }


    @ApiOperation(value = "得到当前用户信息" )
    @GetMapping(value = "/user/info")
    public R userInfo(){
        AdminLoginVO  adminLoginVO= AdminInfoUtil.getAdmin();

        Map<String,Object> data=new HashMap<>();

        data.put("user", adminLoginVO.getSysUser());
        data.put("isSuperMan",adminLoginVO.isSuperMan());

        if(this.userPermisson){
            //如果想要实时的权限,查询数据库
            SysRole sysRole = this.sysRoleService.getById(adminLoginVO.getSysUser().getRoleId());

            Set<String> roleSet =new HashSet<>();
            roleSet.add(sysRole.getRoleKey());

            Set<String> permSet=this.sysMenuService.searchUserOwnPerm(adminLoginVO.getSysUser().getUserId());
            data.put("roles", roleSet);
            data.put("permissions", permSet);
        }else{
            //如果取得登录的时候缓存权限
            data.put("roles", adminLoginVO.getRoleSet());
            data.put("permissions", adminLoginVO.getPermsSet());
        }
        return R.okHasData(data);
    }

    @RequiresLogin
    @ApiOperation(value = "获取当前用户的动态路由信息",hidden = true)
    @GetMapping("/getRouters")
    public R getRouters() {
        AdminLoginVO adminLoginVO= AdminInfoUtil.getAdmin();
        Long userId = adminLoginVO.getSysUser().getUserId();
        // 拉取一级菜单
        List<SysMenuVO> menus = sysMenuService.selectMenuTreeByUserId(userId);
        // 返回的是RouterVo列表
        List<RouterVO> routerVOS = sysMenuService.buildMenuRouter(menus);
        return R.okHasData(routerVOS);
    }
}
